//设置接入的设备模式 ---灯
#define BLINKER_WIFI
#define BLINKER_MIOT_LIGHT
#include "logo.h"
#include <Blinker.h>
#define WUHAN 420100
#include <GxEPD.h>
#include <GxGDEH0154D67/GxGDEH0154D67.h>  // 1.54" b/w
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>
#include <Fonts/FreeMonoBold24pt7b.h>
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16); // arbitrary selection of 17, 16
GxEPD_Class display(io, /*RST=*/ 16, /*BUSY=*/ 4); // arbitrary selection of (16), 4
//WiFi连接
//待优化
char auth[] = "86a437649560";
char ssid[] = "TEST";
char pswd[] = "zyx123456";

//
#include <Adafruit_NeoPixel.h>
#define BTN_SW         "btn_led_sw"//开关组件的键值
#define PIN            2//彩灯引脚
#define NUMPIXELS      24//像素值
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


//创建组件信息
#define Slider_led "SliderKey"
#define RGB_1 "RGBKey"
//创建组件对象
BlinkerRGB WS2812(RGB_1);//创建一个手机端的RGB对象
BlinkerButton Button_sw(BTN_SW);//开关组件
BlinkerSlider Slider1(Slider_led);
String msgData = "";
int8_t last_min = 0;
int8_t last_hou = 0;
typedef struct getTime{
  int8_t getHour;
  int8_t getMin;
  int8_t getSec;
} getTime;

getTime timeNow;

uint8_t colorR, colorG, colorB, colorW;//三色灯
bool wsState;
uint8_t wsMode = BLINKER_CMD_MIOT_DAY;
void msgDataUpdata(void);
void pixelShow()
{
    pixels.setBrightness(colorW);

    for(int i = 0; i < NUMPIXELS; i++){
        pixels.setPixelColor(i, colorR, colorG, colorB);
    }
    pixels.show();
}



//=========================================小爱同学的相关接口====================================




void ws2812_callback(uint8_t r_value, uint8_t g_value, uint8_t b_value, uint8_t bright_value)
{ 
    
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    wsState = true;
    BLINKER_LOG("R value: ", r_value);
    BLINKER_LOG("G value: ", g_value);
    BLINKER_LOG("B value: ", b_value);
    BLINKER_LOG("Rrightness value: ", bright_value);

    colorR = r_value;
    colorG = g_value;
    colorB = b_value;
    colorW = bright_value;

    pixelShow();
}

uint32_t getColor()
{
    uint32_t color = colorR << 16 | colorG << 8 | colorB;

    return color;
}

void miotPowerState(const String & state)
{
    BLINKER_LOG("need set power state: ", state);

    if (state == BLINKER_CMD_ON) {
        digitalWrite(LED_BUILTIN, HIGH);

        BlinkerMIOT.powerState("on");
        BlinkerMIOT.print();

        wsState = true;
    }
    else if (state == BLINKER_CMD_OFF) {
        digitalWrite(LED_BUILTIN, LOW);

        BlinkerMIOT.powerState("off");
        BlinkerMIOT.print();

        wsState = false;
        colorW = 0;
    }

    pixelShow();
}

void miotColor(int32_t color)
{
    BLINKER_LOG("need set color: ", color);

    colorR = color >> 16 & 0xFF;
    colorG = color >>  8 & 0xFF;
    colorB = color       & 0xFF;

    BLINKER_LOG("colorR: ", colorR, ", colorG: ", colorG, ", colorB: ", colorB);

    pixelShow();

    BlinkerMIOT.color(color);
    BlinkerMIOT.print();
}

void miotMode(uint8_t mode)
{
    BLINKER_LOG("need set mode: ", mode);

    if (mode == BLINKER_CMD_MIOT_DAY) {
        // Your mode function
    }
    else if (mode == BLINKER_CMD_MIOT_NIGHT) {
        // Your mode function
    }
    else if (mode == BLINKER_CMD_MIOT_COLOR) {
        // Your mode function
    }
    else if (mode == BLINKER_CMD_MIOT_WARMTH) {
        // Your mode function
    }
    else if (mode == BLINKER_CMD_MIOT_TV) {
        // Your mode function
    }
    else if (mode == BLINKER_CMD_MIOT_READING) {
        // Your mode function
    }
    else if (mode == BLINKER_CMD_MIOT_COMPUTER) {
        // Your mode function
    }

    wsMode = mode;

    BlinkerMIOT.mode(mode);
    BlinkerMIOT.print();
}

void miotBright(const String & bright)
{
    BLINKER_LOG("need set brightness: ", bright);

    colorW = bright.toInt();

    BLINKER_LOG("now set brightness: ", colorW);

    pixelShow();

    BlinkerMIOT.brightness(colorW);
    BlinkerMIOT.print();
}

void miotColoTemp(int32_t colorTemp)
{
    BLINKER_LOG("need set colorTemperature: ", colorTemp);

    BlinkerMIOT.colorTemp(colorTemp);
    BlinkerMIOT.print();
}

void miotQuery(int32_t queryCode)
{
    BLINKER_LOG("MIOT Query codes: ", queryCode);

    switch (queryCode)
    {
        case BLINKER_CMD_QUERY_ALL_NUMBER :
            BLINKER_LOG("MIOT Query All");
            BlinkerMIOT.powerState(wsState ? "on" : "off");
            BlinkerMIOT.color(0);
            BlinkerMIOT.mode(0);
            BlinkerMIOT.colorTemp(1000);
            BlinkerMIOT.brightness(1);
            BlinkerMIOT.print();
            break;
        case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :
            BLINKER_LOG("MIOT Query Power State");
            BlinkerMIOT.powerState(wsState ? "on" : "off");
            BlinkerMIOT.print();
            break;
        case BLINKER_CMD_QUERY_COLOR_NUMBER :
            BLINKER_LOG("MIOT Query Color");
            BlinkerMIOT.color(0);
            BlinkerMIOT.print();
            break;
        case BLINKER_CMD_QUERY_MODE_NUMBER :
            BLINKER_LOG("MIOT Query Mode");
            BlinkerMIOT.mode(0);
            BlinkerMIOT.print();
            break;
        case BLINKER_CMD_QUERY_COLORTEMP_NUMBER :
            BLINKER_LOG("MIOT Query ColorTemperature");
            BlinkerMIOT.colorTemp(1000);
            BlinkerMIOT.print();
            break;
        case BLINKER_CMD_QUERY_BRIGHTNESS_NUMBER :
            BLINKER_LOG("MIOT Query Brightness");
            BlinkerMIOT.brightness(1);
            BlinkerMIOT.print();
            break;
        default :
            BlinkerMIOT.powerState(wsState ? "on" : "off");
            BlinkerMIOT.color(0);
            BlinkerMIOT.mode(0);
            BlinkerMIOT.colorTemp(1000);
            BlinkerMIOT.brightness(1);
            BlinkerMIOT.print();
            break;
    }
}

void dataRead(const String & data)
{
    BLINKER_LOG("Blinker readString: ", data);

    Blinker.vibrate();
    
    uint32_t BlinkerTime = millis();
    
    Blinker.print("millis", BlinkerTime);
    msgData = data;
    msgDataUpdata();
    
}
//=========================回调函数相关=============================
void button_sw_callback(const String & state){//按键的回调函数，打开或者关闭灯
  wsState = !wsState;
  digitalWrite(LED_BUILTIN, wsState);
  pixelShow();
}

void drawLogo(void)
{
  display.eraseDisplay();
  display.drawBitmap(gImage_mine, 0, 0,200,200, GxEPD_WHITE);
}
//屏幕时间显示更新
void timeupDate(void){
    
    //display.drawRect(1,1,199,199,GxEPD_BLACK);
    display.drawLine(1,62,200,62,GxEPD_BLACK);
    display.setRotation(0);
    display.fillRect(0, 0, 200,60, GxEPD_WHITE);
    display.updateWindow(0, 0, 200,60,true);
    display.setFont(&FreeMonoBold18pt7b);
    display.setTextColor(GxEPD_BLACK);    
    display.setCursor(40, 30);
    display.print(timeNow.getHour);
    display.print(":");
    display.print(timeNow.getMin); 
    //display.updateWindow(2,2,195,50,true);
}

void msgDataUpdata(void){
    
    display.setRotation(0);
    display.fillRect(2, 65, 198,130, GxEPD_WHITE);
    display.updateWindow(2, 65, 198,130,true);
    display.setFont(&FreeMonoBold9pt7b);
    display.setTextColor(GxEPD_BLACK);    
    display.setCursor(20, 80);
    display.print(msgData);
    display.updateWindow(1, 65, 198,130,true);
    //display.updateWindow(1,2,195,50,true);
}

void weatherData(const String & data) {//天气回调函数
    BLINKER_LOG("weather: ", data);
}
void displayUpdate(){
  static unsigned char updateTimes = 0;  
  if(updateTimes>5||last_hou!=timeNow.getHour){
    timeupDate();
    msgDataUpdata();
    display.update();
    
    last_hou = timeNow.getHour;
    updateTimes = 0;
  }
  else if(last_min != timeNow.getMin){
    timeupDate();
    display.updateWindow(2,2,195,50,true);
    //msgDataUpdata();
    last_min = timeNow.getMin;
    updateTimes++;
  }


  
  
}
void setup()
{
    Serial.begin(115200);    
    BLINKER_DEBUG.stream(Serial);
    BLINKER_DEBUG.debugAll();

    pinMode(LED_BUILTIN, OUTPUT);
    pinMode(13,OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(13,HIGH);
    // ledcAttachPin(LED_BUILTIN,1);
    // ledcSetup(1,100000,8);

    ledcSetup(0,1000,13);
    ledcAttachPin(35,0);
    ledcWrite(0,125);
    do{
    Blinker.begin(auth, ssid, pswd);
    Blinker.delay(500);
    }while(Blinker.init());
    ledcWrite(0,125); 
 // ATTACH CALL BACK FUNCTION
    Button_sw.attach(button_sw_callback);
    // Slider1.attach(slider1_callback);
    Blinker.attachWeather(weatherData);

    Blinker.attachData(dataRead);
    
    BlinkerMIOT.attachPowerState(miotPowerState);
    BlinkerMIOT.attachColor(miotColor);
    BlinkerMIOT.attachMode(miotMode);
    BlinkerMIOT.attachBrightness(miotBright);
    BlinkerMIOT.attachColorTemperature(miotColoTemp);
    BlinkerMIOT.attachQuery(miotQuery);

    pinMode(14, OUTPUT);
    digitalWrite(14, HIGH);
    pinMode(15, OUTPUT);
    digitalWrite(15, HIGH);

    colorR = 255;
    colorG = 255;
    colorB = 255;
    colorW = 0;
    wsState = true;
    //ledState = true;

    pixels.begin();
    pixels.setBrightness(colorW);
    WS2812.attach(ws2812_callback);
    //pixelShow();
    display.init();
    display.eraseDisplay();
    display.drawPaged(drawLogo);
    delay(2000);
    display.eraseDisplay();
    timeupDate();

}


void loop()
{   
    Blinker.run();
    timeNow.getHour =  Blinker.hour();
    timeNow.getMin  =  Blinker.minute();
    timeNow.getSec  =  Blinker.second();
    displayUpdate();
    
}
